package org.lex.jdbc.util;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.dbutils.ResultSetHandler;

/**
 * <code>ResultSetHandler</code> implementation that converts one
 * <code>ResultSet</code> column into a <code>List</code> of
 * <code>Object[]</code>s. This class is thread safe.
 * 
 * @see org.apache.commons.dbutils.ResultSetHandler
 */
public class ColumnsArrayListHandler implements ResultSetHandler<List<Object[]>> {

	/**
	 * The column number to retrieve.
	 */
	private int[] columnIndies = null;

	/**
	 * The column name to retrieve. Either columnName or columnIndex will be
	 * used but never both.
	 */
	private String[] columnNames = null;

	private boolean useIndex = true;

	/**
	 * Creates a new instance of ColumnListHandler.
	 * 
	 * @param columnIndex
	 *            The index of the column to retrieve from the
	 *            <code>ResultSet</code>.
	 */
	public ColumnsArrayListHandler(int... columnIndex) {
		this.columnIndies = columnIndex;
		this.useIndex = true;
	}

	/**
	 * Creates a new instance of ColumnListHandler.
	 * 
	 * @param columnName
	 *            The name of the column to retrieve from the
	 *            <code>ResultSet</code>.
	 */
	public ColumnsArrayListHandler(String... columnName) {
		this.columnNames = columnName;
		this.useIndex = false;
	}

	/**
	 * Whole <code>ResultSet</code> handler. It produce <code>List</code> as
	 * result. To convert individual rows into Java objects it uses
	 * <code>handleRow(ResultSet)</code> method.
	 * 
	 * @see #handleRow(ResultSet)
	 */
	public List<Object[]> handle(ResultSet rs) throws SQLException {
		List<Object[]> rows = new ArrayList<Object[]>();
		while (rs.next()) {
			rows.add(this.handleRow(rs));
		}
		return rows;
	}

	/**
	 * Returns one <code>ResultSet</code> column value as <code>Object</code>.
	 * 
	 * @return <code>Object</code>, never <code>null</code>.
	 * 
	 * @throws SQLException
	 *             if a database access error occurs
	 */
	protected Object[] handleRow(ResultSet rs) throws SQLException {
		Object[] result = null;
		int i = 0;
		if (true == this.useIndex) {
			result = new Object[this.columnIndies.length];
			for (int index : this.columnIndies) {
				result[i++] = rs.getObject(index);
			}
		} else {
			result = new Object[this.columnNames.length];
			for (String name : this.columnNames) {
				result[i++] = rs.getObject(name);
			}
		}
		return result;
	}
}
